import Snake from "./Snake";
import Food from "./Food";
import ScorePanel from "./ScorePanel";

class GameControl {
    private snake: Snake;
    private food: Food;
    private scorePanel: ScorePanel;
    private direction = '';
    private isAlive = true;

    constructor() {
        this.snake = new Snake();
        this.food = new Food();
        this.scorePanel = new ScorePanel(100, 10);

        this.init();
    }

    init() {
        document.addEventListener('keydown', this.keydownHandler.bind(this));
        this.run();
    }

    /**
     *   ArrowUp    Up
     ArrowDown  Down
     ArrowLeft  Left
     ArrowRight Right
     * @param event
     */
    keydownHandler(event: KeyboardEvent) {
        // 取消默认
        event.preventDefault();
        this.direction = event.key;
        // this.run();
    }

    /**
     * 根据方向（this.direction）来使蛇的位置改变
     向上 top 减少
     向下 top 增加
     向左  left 减少
     向右  left 增加
     */
    run() {
        let x = this.snake.x;
        let y = this.snake.y;
        switch (this.direction) {
            case "ArrowUp":
            case "Up":
                y -= 10;
                break;
            case "ArrowDown":
            case "Down":
                y += 10;
                break;
            case "ArrowLeft":
            case "Left":
                x -= 10;
                break;
            case "ArrowRight":
            case "Right":
                x += 10;
                break;
            default:
                break;
        }

        this.eatFood(x, y);

        try {
            this.snake.x = x;
            this.snake.y = y;
        } catch (e) {
            alert(`${e.message}，GAME OVER!`);
            this.isAlive = false;
        }

        // 开启一个定时调用
        if (this.isAlive) {
            setTimeout(this.run.bind(this), 300 - (this.scorePanel.level - 1) * 30);
        }
    }

    /**
     *检查蛇是否吃到食物
     * @param x
     * @param y
     */
    private eatFood(x: number, y: number) {
        if (this.food.x === x && this.food.y === y) {
            this.food.respawn(this.snake.xYs);
            this.scorePanel.addScore();
            this.snake.addBody();
        }
    }
}

export default GameControl;